/*++

Copyright (c) 2016 Minoca Corp.

    This file is licensed under the terms of the GNU General Public License
    version 3. Alternative licensing terms are available. Contact
    info@minocacorp.com for details. See the LICENSE file at the root of this
    project for complete licensing information.

Module Name:

    minttbl.S

Abstract:

    This module implements the monitor mode interrupt jump vector table for the
    RK3288 Veyron SoC.

Author:

    Chris Stevens 8-Jun-2016

Environment:

    Firmware

--*/

//
// ------------------------------------------------------------------ Includes
//

#include <minoca/kernel/arm.inc>

//
// --------------------------------------------------------------- Definitions
//

//
// ---------------------------------------------------------------------- Code
//

ASSEMBLY_FILE_HEADER
.arch_extension virt

//
// .globl allows these labels to be visible to the linker.
//

.globl EfipRk32MonitorInterruptTable

//
// This address must be aligned to a 32 byte address so that it can be set in
// the MVBAR register.
//

.balign 32

EfipRk32MonitorInterruptTable:
.word 0
.word 0
    ldr     %pc, EfipRk32SecureMonitorCallVector
    ldr     %pc, EfipRk32PrefetchAbortVector
    ldr     %pc, EfipRk32DataAbortVector
.word 0
    ldr     %pc, EfipRk32IrqInterruptVector
    ldr     %pc, EfipRk32FiqInterruptVector

EfipRk32SecureMonitorCallVector:
    .word EfipRk32SecureMonitorCallEntry

EfipRk32PrefetchAbortVector:
    .word 0

EfipRk32DataAbortVector:
    .word 0

EfipRk32IrqInterruptVector:
    .word 0

EfipRk32FiqInterruptVector:
    .word 0

//
// --------------------------------------------------------- Internal Functions
//

//
// VOID
// EfipRk32SecureMonitorCallEntry (
//     VOID
//     )
//

/*++

Routine Description:

    This routine directly handles an exception generated by a secure monitor
    call.

Arguments:

    None.

Return Value:

    None.

--*/

FUNCTION EfipRk32SecureMonitorCallEntry

    //
    // The ARM Generic Timer's virtual offset can bet set in HYP mode and in
    // Monitor Mode when the SCR.NS bit is set to 1. Set the NS bit and zero
    // the offset.
    //

    mrc     p15, 0, %r0, %c1, %c1, 0          @ Get the SCR
    orr     %r0, %r0, #SCR_NON_SECURE
    mcr     p15, 0, %r0, %c1, %c1, 0          @ Set the SCR
    mov     %r2, #0
    mov     %r3, #0
    mcrr    p15, 4, %r2, %r3, %c14

    //
    // Clear the NS bit before returing from the exception to remain in secure
    // mode.
    //

    bic     %r0, %r0, #SCR_NON_SECURE
    mcr     p15, 0, %r0, %c1, %c1, 0          @ Set the SCR
    eret

END_FUNCTION EfipRk32SecureMonitorCallEntry

